#pragma once

#include <QWidget>
#include <QList>
#include <QMap>
#include <QSet>
#include <QString>
#include <QMutex>
#include "piocore.h"

class MediaItem;
class IconCache;

class CollectionView : public QWidget
{
	Q_OBJECT
public:

    class Header {
    public:
        QString title;
        QRect rect;
        QSet<QString> tags;
        QList<MediaItemPtr> items;
    };
    enum Grouping {
        GroupEvent, GroupDay, GroupMonth
    };

    CollectionView(QWidget * parent = 0);
    void setCore(PioCore * core);
    void setIconCache(IconCache * cache);
    void grouping(Grouping grouping) { m_grouping = grouping; }

signals:
    void makeVisible(const QRect & rect);
    void view(MediaItemPtr item);
    void setVerticalPosition(int y);
    void contextMenuRequested();
    void fullscreen(bool fullscreen);
    void status(const QString & str);

public slots:
    void onAdd(MediaItemPtr item);
    void onRemove(MediaItemPtr item);
    void onUpdate(MediaItemPtr item);
    void large_thumbnails();
    void medium_thumbnails();
    void small_thumbnails();
    void onSetVerticalPosition(int y);
    void left();
    void right();
    void up();
    void down();
    void begin();
    void end();

private slots:
    void updateGeom();
    void onSelectionChanged(QList<MediaItemPtr> selection);
    void onLoaded(MediaItemPtr item, QSize size, QSharedPointer<QPixmap> icon);

protected:
    virtual void paintEvent(QPaintEvent *);
    virtual void resizeEvent(QResizeEvent *);
    virtual void mouseDoubleClickEvent(QMouseEvent *);
    virtual void mousePressEvent(QMouseEvent *);
    virtual void mouseMoveEvent(QMouseEvent *);
    virtual void mouseReleaseEvent(QMouseEvent *);
    virtual void contextMenuEvent(QContextMenuEvent *);
    virtual void keyPressEvent(QKeyEvent *);

private slots:
    void checkCacheStatus();
    void makeVisible(MediaItemPtr item);
    void updateItem(MediaItemPtr item);

private:
    enum SelectionMode {
        SetSelection,
        AddSelection,
        ToggleSelection
    };

    void schedule_update();
    MediaItemPtr itemAt(const QPoint & pos);
    QList<MediaItemPtr> itemsAt(const QRect & rect);

    void select(MediaItemPtr & item, SelectionMode mode = SetSelection);
    SelectionMode getSelectionMode(Qt::KeyboardModifiers modifiers);
    bool split(const MediaItem & a, const MediaItem & b);
    QColor color(double val);
    MediaItemPtr cursor();

    PioCore * m_core;
    IconCache * m_cache;

    QList<MediaItemPtr> m_items;
    QList<Header> m_headers;
    QMap<MediaItemPtr, int> m_headermap;

    int m_item_width;
    int m_item_height;
    int m_margin;
    int m_title_height;
    bool m_update_scheduled;
    bool m_restore_vertical_position;

    QFont m_title_font;
    QFont m_tags_font;
    QBrush m_gradient;
    QColor m_color1, m_color2;

    Grouping m_grouping;

    bool m_crop;

    enum {
        Click,
        DoubleClick,
        SelectItems,
        DragItems
    } m_mouseAction;

    QPoint m_start_pos;
    //Qt::KeyboardModifiers m_start_modifiers;
    Qt::MouseButtons m_start_buttons;
    QRect m_selection_rect;
    int m_verticalPosition;
    QMutex m_mutex;
    bool m_cacheQueueStatus;
    QSet<MediaItemPtr> m_selection;
    QPixmap m_check;
};
